﻿package lz.controls.scroll
{
    import flash.geom.*;
    import flash.display.*;
    import flash.events.*;

    public class BasicScroll extends EventDispatcher 
	{

        private var _scroll:MovieClip = null;
        private var _upBtn:SimpleButton = null;
        private var _downBtn:SimpleButton = null;
        private var _track:Sprite = null;
        private var _sliderBar:MovieClip = null;
        private var _sliderBarControl:SliderBar = null;
        private var _maxLength:int = 0;
        private var _minLength:int = 0;
        private var _totalLength:Number = 0;
        private var _distance:Number = 0;
        private var _perPlace:Number;
        private var _totalPlace:Number = 0;
        private var _currentPlace:Number = 0;
        private var _btnStep:int = 5;
        private var _scrollStep:Number = 0;
        private var _wheelStep:Number = 5;
        private var _upBtnX:Number = 0;
        private var _upBtnY:Number = 0;
        private var _downBtnX:Number = 0;
        private var _downBtnY:Number = 0;
        private var _minY:Number = 0;
        private var _maxY:Number = 0;
        private var _isDown:Boolean = false;
        private var _isUp:Boolean = false;

        public function BasicScroll(_mc:MovieClip)
		{
            _scroll = _mc;
            _upBtn = _mc.upBtn;
            _downBtn = _mc.downBtn;
            _sliderBarControl = new SliderBar(_scroll.sliderBar);
            _sliderBar = _scroll.sliderBar;
            _minY = _upBtn.getBounds(_scroll).y + _upBtn.getBounds(_scroll).height;
            _maxY = _downBtn.getBounds(_scroll).y;
            _minY = Math.round(_minY);
            _maxY = Math.round(_maxY);
            _sliderBar.y = _minY;
            _track = new Sprite();
            _track.graphics.beginFill(0xFFFFFF, 0);
            _track.graphics.drawRect(0, _minY, _sliderBar.width, (_maxY - _minY));
            _track.graphics.endFill();
            _sliderBar.parent.getChildIndex(_sliderBar);
            _scroll.addChildAt(_track, _sliderBar.parent.getChildIndex(_sliderBar));
        }
        public function setScroll(showH:Number, overH:Number):void
		{
            _sliderBar.y = _minY;
            _currentPlace = 0;
            if (overH > 0)
			{
                _sliderBarControl.height = ((showH * (_maxY - _minY)) / (overH + showH));
            }
            _distance = ((_maxY - _minY) - _sliderBar.getBounds(_scroll).height);
            _distance = Math.round(_distance);
            _perPlace = showH;
            _totalPlace = overH;
            _maxLength = ((_track.height - _sliderBar.top.height) - _sliderBar.bottom.height);
            _minLength = 30;
            if (overH <= 0)
			{
                _totalPlace = 0;
                _sliderBarControl.hideBar();
                removeEvent();
            } else 
			{
                _sliderBarControl.showBar();
                addEvent();
            }
        }
        private function addEvent():void
		{
            _upBtn.addEventListener(MouseEvent.MOUSE_DOWN, clickBtnHandler);
            _downBtn.addEventListener(MouseEvent.MOUSE_DOWN, clickBtnHandler);
            _sliderBar.addEventListener(MouseEvent.MOUSE_DOWN, onsliderBarDown);
            _scroll.parent.addEventListener(MouseEvent.MOUSE_WHEEL, onsliderBarWheel);
            _track.addEventListener(MouseEvent.CLICK, onTrackClickHandler);
        }
        private function removeEvent():void
		{
            _upBtn.removeEventListener(MouseEvent.MOUSE_DOWN, clickBtnHandler);
            _downBtn.removeEventListener(MouseEvent.MOUSE_DOWN, clickBtnHandler);
            _sliderBar.removeEventListener(MouseEvent.MOUSE_DOWN, onsliderBarDown);
            _scroll.parent.removeEventListener(MouseEvent.MOUSE_WHEEL, onsliderBarWheel);
            _track.removeEventListener(MouseEvent.CLICK, onTrackClickHandler);
        }
        private function clickBtnHandler(e:MouseEvent):void
		{
            if (e.currentTarget == _upBtn)
			{
                _currentPlace = (_currentPlace - _btnStep);
                _sliderBar.y = (_sliderBar.y - ((_btnStep * _distance) / _totalPlace));
                _isUp = true;
                _isDown = false;
            } else 
			{
                if (e.currentTarget == _downBtn)
				{
                    _currentPlace = (_currentPlace + _btnStep);
                    _sliderBar.y = (_sliderBar.y + ((_btnStep * _distance) / _totalPlace));
                    _isUp = false;
                    _isDown = true;
                }
            }
            _scroll.addEventListener(Event.ENTER_FRAME, scrollHandler);
            _scroll.stage.addEventListener(MouseEvent.MOUSE_UP, stopScroll);
            determineLocation();
            eventSend();
        }
        private function scrollHandler(e:Event):void
		{
            if (_isUp)
			{
                _currentPlace = (_currentPlace - _btnStep);
                _sliderBar.y = (_sliderBar.y - ((_btnStep * _distance) / _totalPlace));
            }
            if (_isDown)
			{
                _currentPlace = (_currentPlace + _btnStep);
                _sliderBar.y = (_sliderBar.y + ((_btnStep * _distance) / _totalPlace));
            }
            determineLocation();
            eventSend();
        }
        private function stopScroll(e:MouseEvent):void
		{
            _scroll.removeEventListener(Event.ENTER_FRAME, scrollHandler);
        }
        private function determineLocation():Boolean
		{
            if (_currentPlace >= _totalPlace)
			{
                _currentPlace = _totalPlace;
                _sliderBar.y = (_minY + _distance);
                return false;
            }
            if (_currentPlace <= 0)
			{
                _currentPlace = 0;
                _sliderBar.y = _minY;
                return false;
            }
            return true;
        }
        private function onsliderBarDown(e:MouseEvent):void
		{
            _sliderBar.startDrag(false, new Rectangle(0, _minY, 0, _distance));
            _sliderBar.addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
            _sliderBar.stage.addEventListener(MouseEvent.MOUSE_UP, onsliderBarUp);
        }
        private function onsliderBarUp(e:MouseEvent):void
		{
            e.currentTarget.removeEventListener(e.type, arguments.callee);
            _sliderBar.stopDrag();
            _sliderBar.removeEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
        }
        private function onTrackClickHandler(e:MouseEvent):void
		{
            _sliderBar.y = (_track.mouseY - (_sliderBar.getBounds(_scroll).height / 2));
            _currentPlace = ((_totalPlace * (_sliderBar.y - _minY)) / _distance);
            determineLocation();
            eventSend();
        }
        private function onsliderBarWheel(e:MouseEvent):void
		{
            var dist:*;
            if (e.delta != 0)
			{
				dist = ((Math.abs(e.delta) * _wheelStep) / e.delta);
                _currentPlace = (_currentPlace - dist);
                _sliderBar.y = (_sliderBar.y - ((dist * _distance) / _totalPlace));
                determineLocation();
                eventSend();
            }
        }
        private function onEnterFrameHandler(e:Event):void
		{
            var dist:Number = ((_sliderBar.y - _minY) / _distance);
            if (dist < 0)
			{
				dist = 0;
            }
            if (dist > 1)
			{
				dist = 1;
            }
            _currentPlace = ((_totalPlace * (_sliderBar.y - _minY)) / _distance);
            if ((_totalPlace - _currentPlace) <= 0.5)
			{
                _currentPlace = _totalPlace;
            }
            eventSend();
        }
        private function eventSend():void
		{
            dispatchEvent(new Event(Event.CHANGE));
        }
        public function set currentPlace(value:Number):void
		{
            _currentPlace = value;
            _sliderBar.y = (((_currentPlace * _distance) / _totalPlace) + _minY);
            determineLocation();
        }
        public function get currentPlace():Number
		{
            return _currentPlace;
        }
        public function set btnstep(value:int):void
		{
            _btnStep = value;
            _scrollStep = (_distance / (_totalPlace / _btnStep));
        }
        public function set wheelStep(value:Number):void
		{
            _wheelStep = value;
        }
        public function get totalPlace():int
		{
            return ((_totalPlace + _perPlace));
        }
    }
}
